1. 问题
result = exp1 ? value1 : exp2 ? value2 : value3;
上述表达式中result的类型是什么?
2. 解答
- 前置知识:
- 浮点型大于整形,Double大于Float,Long大于Integer,Integer大于Short,Short大于Byte(大于是指不同类型变量计算时返回大的类型)
- 整数默认类型为Integer、浮点数默认类型为Double
- 基本类型和包装类型混用时,包装类型会自动拆箱为基本类型
- 分类讨论:
- 当且仅当value1、value2和value3为相同的包装类型时,返回值类型为包装类型;若不同,根据规则1,返回值类型为相应的基本类型
- char和Character在和其他数值类型的变量运算中,总是隐式的转换为int类型
- 当value1、value2和value3中包含String、boolean、Boolean类型值,且不含reference类型值时,返回值类型为Serializable类型
- 当value1、value2和value3中存在reference类型时,返回值为Object类型
3. 意义
- 自动拆箱时,有可能发生NullPointException,需要谨慎使用三目运算符的嵌套形式:
- 如
flag ? 1 : null
这样的用法是没有问题的,该表达式的返回值是Integer类型 - 而
flag1 ? 1 : flag2 ? 2 : null
,当flag1和flag2均为false时,会发生NullPointException- 因为该表达式的返回值类型为int,是基本类型,而null不是基本类型,所以需要自动拆箱将值赋给返回值,而“
null.intValue()
”当然会导致发生NullPointException - 即使使用Integer类型的变量去接该返回值,同样还是会发生NullPointException,因为该表达式的返回值类型是确定的(int类型),使用Integer类型接返回值时,只不过是隐式的使用了自动装箱,而自动装箱之前的自动拆箱过程仍是有异常的
- 因为该表达式的返回值类型为int,是基本类型,而null不是基本类型,所以需要自动拆箱将值赋给返回值,而“
- 如
4. 代码
public class Test {
private static void test(boolean flag1, boolean flag2) {
Double d = flag1 ? new Double(1d) : flag2 ? new Double(2d) : new Double(3d);
Float f = flag1 ? new Float(1f) : flag2 ? new Float(2f) : new Float(3f);
Long l = flag1 ? new Long(1L) : flag2 ? new Long(2L) : new Long(